/**
 * 
 */
package com.ffcs.crmd.tsp.server.netty.processor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ffcs.crmd.tsp.api.dto.client.TspJobDetailTrack;
import com.ffcs.crmd.tsp.api.dto.netty.RemotingCommand;
import com.ffcs.crmd.tsp.api.dto.page.PageInfo;
import com.ffcs.crmd.tsp.api.dto.page.RetVo;
import com.ffcs.crmd.tsp.api.netty.INettyProcessor;
import com.ffcs.crmd.tsp.common.constant.LoggerName;
import com.ffcs.crmd.tsp.common.netty.ResponseCode;
import com.ffcs.crmd.tsp.core.util.RemotingUtil;
import com.ffcs.crmd.tsp.core.util.XmlUtil;
import com.ffcs.crmd.tsp.server.application.ApplicationManagerHolder;
import com.ffcs.crmd.tsp.server.core.DataBaseHandler;
import com.ffcs.crmd.tsp.server.core.QuartzSchedulerHandler;
import com.ffcs.crmd.tsp.server.core.RemotingHandler;
import com.ffcs.crmd.tsp.server.job.info.JobDetailTrack;
import com.ffcs.crmd.tsp.server.job.info.JobDetailTrackInfo;
import com.ffcs.crmd.tsp.server.manager.JobProcessManager;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;

/**
 * 功能说明:
 *
 * @author ZHONGFUHUA
 * 
 * @since 
 *
 */
public class QueryJobDetailTrackProcessor implements INettyProcessor {
    
    /**
     * 日志
     */
    private final static Logger LOG               = LoggerFactory.getLogger(LoggerName.RemotingLoggerName);
    
    /**
     * 任务端管理器
     */
    private JobProcessManager   jobProcessManager = ApplicationManagerHolder.getBean("jobProcessManager", JobProcessManager.class);
    
    /**
     * 功能说明:
     * 
     * @param remotingController
     */
    public QueryJobDetailTrackProcessor(RemotingHandler remotingController, DataBaseHandler dataBaseHandler) {
    }
    
    @Override
    public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) {
        RemotingCommand response = RemotingCommand.createResponseCommand(ResponseCode.SUCCESS);
        String requestXml = new String(request.getBody());
        try {
            LOG.info("SERVER-NETTY: one request to query job detail track is received that body=[{}]", requestXml);
            TspJobDetailTrack tspJobDetailDeathTrackVO = (TspJobDetailTrack) XmlUtil.fromXml(requestXml, TspJobDetailTrack.class);
            
            List<TspJobDetailTrack> tspJobDetailDeathTrackList = new ArrayList<TspJobDetailTrack>();
            RetVo<TspJobDetailTrack> retVo = new RetVo<TspJobDetailTrack>();
            
            JobDetailTrack jobDetailTransferTrack = jobProcessManager.getJobDetailTrack(tspJobDetailDeathTrackVO.getJobName(),
                tspJobDetailDeathTrackVO.getId());
            if (jobDetailTransferTrack != null) {
                Iterator<Entry<Channel, Map<Integer, JobDetailTrackInfo>>> it = jobDetailTransferTrack.getChannelInfo().entrySet().iterator();
                while (it.hasNext()) {
                    Entry<Channel, Map<Integer, JobDetailTrackInfo>> entry = it.next();
                    Channel channel = entry.getKey();
                    Map<Integer, JobDetailTrackInfo> jobDetailTrackInfoMap = entry.getValue();
                    Iterator<Entry<Integer, JobDetailTrackInfo>> jobDetailTrackInfoIt = jobDetailTrackInfoMap.entrySet().iterator();
                    while (jobDetailTrackInfoIt.hasNext()) {
                        Entry<Integer, JobDetailTrackInfo> jobDetailTrackInfoEntry = jobDetailTrackInfoIt.next();
                        JobDetailTrackInfo jobDetailTrackInfo = jobDetailTrackInfoEntry.getValue();
                        Integer opaque = jobDetailTrackInfoEntry.getKey();
                        TspJobDetailTrack ntspJobDetailDeathTrack = new TspJobDetailTrack();
                        ntspJobDetailDeathTrack.setOpaque(opaque);
                        ntspJobDetailDeathTrack.setSendTime(jobDetailTrackInfo.getSendTime());
                        ntspJobDetailDeathTrack.setFireTime(jobDetailTrackInfo.getFireTime());
                        ntspJobDetailDeathTrack.setReciveTime(jobDetailTrackInfo.getReciveTime());
                        ntspJobDetailDeathTrack.setCompleteTime(jobDetailTrackInfo.getCompleteTime());
                        ntspJobDetailDeathTrack.setJobName(tspJobDetailDeathTrackVO.getJobName());
                        ntspJobDetailDeathTrack.setInstanceId(QuartzSchedulerHandler.getInstanceId());
                        ntspJobDetailDeathTrack.setClusterName(QuartzSchedulerHandler.getClusterName());
                        ntspJobDetailDeathTrack.setAddr(RemotingUtil.parseChannelRemote(channel));
                        tspJobDetailDeathTrackList.add(ntspJobDetailDeathTrack);
                    }
                }
            }
            
            Collections.sort(tspJobDetailDeathTrackList, new Comparator<TspJobDetailTrack>() {
                @Override
                public int compare(TspJobDetailTrack o1, TspJobDetailTrack o2) {
                    return o1.getSendTime().compareTo(o2.getSendTime());
                }
            });
            
            if (tspJobDetailDeathTrackVO.getPageNumber() != null && tspJobDetailDeathTrackVO.getPageSize()!= null 
                && tspJobDetailDeathTrackVO.getPageNumber() > 0 && tspJobDetailDeathTrackVO.getPageSize() > 0) {
                int pageNumber = tspJobDetailDeathTrackVO.getPageNumber();
                int pageSize = tspJobDetailDeathTrackVO.getPageSize();
                int totalCounts = tspJobDetailDeathTrackList.size();
                int first = PageInfo.getPageBeginSize(pageSize, pageNumber);
                int end = PageInfo.getPageEndSize(first, pageSize, totalCounts);
                
                List<TspJobDetailTrack> ntspJobDetailTrackVOList = new ArrayList<TspJobDetailTrack>();
                ntspJobDetailTrackVOList.addAll(tspJobDetailDeathTrackList.subList(first, end));
                
                PageInfo<TspJobDetailTrack> pageInfo = new PageInfo<TspJobDetailTrack>(ntspJobDetailTrackVOList);
                pageInfo.calcAndJudge(pageSize, pageNumber, totalCounts, ntspJobDetailTrackVOList);
                retVo.setPageInfo(pageInfo);
            } else {
                retVo.setDataList(tspJobDetailDeathTrackList);
            }
            response.setBody(XmlUtil.toXml(retVo).getBytes());
        } catch (Exception e) {
            LOG.error("SERVER-NETTY: query job detail track[{}] exception:", requestXml, e);
            String responseBody = String.format("query job detail track exception:%s", e.getMessage());
            response.setCode(ResponseCode.FAIL);
            response.setBody(responseBody.getBytes());
        }
        return response;
    }
    
}
